#ifndef ITERATORDEQUE_H_INCLUDED
#define ITERATORDEQUE_H_INCLUDED

namespace CEngine {

template<class E, class K>
Iterator<E,K>::Iterator(const typename Deque<E>::DequeIterator& it)
    :   type(Deque)
{
    iteratorData.deque.basePointer = it.basePointer;
    iteratorData.deque.currentArray = it.currentArray;
    iteratorData.deque.startElement = it.startPointer;
    iteratorData.deque.currentElement = it.currentPointer;
    iteratorData.deque.endElement = it.endPointer;
    iteratorData.deque.position = it.position;
}

template<class E, class K>
Iterator<E,K>&
Iterator<E,K>::operator=(const typename Deque<E>::DequeIterator& it) {
    type = Deque;
    iteratorData.deque.basePointer = it.basePointer;
    iteratorData.deque.currentArray = it.currentArray;
    iteratorData.deque.startElement = it.startPointer;
    iteratorData.deque.currentElement = it.currentPointer;
    iteratorData.deque.endElement = it.endPointer;
    iteratorData.deque.position = it.position;
    return *this;
}

template<class E, class K>
bool Iterator<E,K>::operator==(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque);

    if(iteratorData.deque.currentElement == it.currentPointer) {
        return true;
    }
    return false;
}

template<class E, class K>
bool Iterator<E,K>::operator!=(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque);

    if(iteratorData.deque.currentElement != it.currentPointer) {
        return true;
    }
    return false;
}

template<class E, class K>
bool Iterator<E,K>::operator>(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque && iteratorData.deque.basePointer == it.basePointer);

    if(iteratorData.deque.position > it.position) {
        return true;
    }
    return false;
}

template<class E, class K>
bool Iterator<E,K>::operator<(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque && iteratorData.deque.basePointer == it.basePointer);

    if(iteratorData.deque.position < it.position) {
        return true;
    }
    return false;
}

template<class E, class K>
bool Iterator<E,K>::operator>=(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque && iteratorData.deque.basePointer == it.basePointer);

    if(iteratorData.deque.position >= it.position) {
        return true;
    }
    return false;
}

template<class E, class K>
bool Iterator<E,K>::operator<=(const typename Deque<E>::DequeIterator& it) const {
    ASSERT(type == Deque && iteratorData.deque.basePointer == it.basePointer);

    if(iteratorData.deque.position <= it.position) {
        return true;
    }
    return false;
}

template<class E, class K> inline
void Iterator<E,K>::dequeRandomAccess(void) {
    iteratorData.deque.currentArray = (iteratorData.deque.basePointer->array.getRawArray() + ((iteratorData.deque.basePointer->start + iteratorData.deque.position) / Constants::Containers::dequeBlockSize));
    iteratorData.deque.startElement = *iteratorData.deque.currentArray;
    iteratorData.deque.currentElement = iteratorData.deque.startElement + ((iteratorData.deque.basePointer->start + iteratorData.deque.position) % Constants::Containers::dequeBlockSize);
    iteratorData.deque.endElement = iteratorData.deque.startElement + Constants::Containers::dequeBlockSize;
}

}

#endif // ITERATORDEQUE_H_INCLUDED
